package com.tqfframe.datamanage.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by Tang-QiFeng on 2022/2/13
 */
@RestController
public class lockStudyController {

    private Logger logger=LoggerFactory.getLogger(this.getClass());

    private Object object=new Object();



    /**
     *  http://localhost:9009/dealOrder/001
     * @param id
     * @return
     */
    @GetMapping(value = "/dealOrder/{id}")
    public String dealOrder(@PathVariable(name="id") String id){
        synchronized (object){
            try {
                logger.info("正在处理订单"+id+"....");
                object.wait();
                logger.info("订单"+id+"被唤醒");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return "订单"+id+"已处理";
    }
    /**
     *  http://localhost:9009/notifyOrder/001
     * @param id
     * @return
     */
    @GetMapping(value = "/notifyOrder/{id}")
    public String notifyOrder(@PathVariable(name="id") String id){
        synchronized (object){
            object.notify();
        }
        return "订单"+id+"已激活";
    }



    /**
     *  http://localhost:9009/reentrantApi/001
     * @param id
     * @return
     */
    @GetMapping(value = "/reentrantApi/{id}")
    public String reentrantApi(@PathVariable(name="id") String id){
        int number=200;
        OrderCore orderCore=new OrderCore(id,number);
        for(int i=50;i>0;i--){
            new Thread(orderCore,"thread-"+i).start();
        }
        return "订单"+id+"已处理";
    }

}

class OrderCore implements Runnable{
    private Logger logger=LoggerFactory.getLogger(this.getClass());
    private String id;
    private volatile int number;
    //可重入锁
    private Lock lock=new ReentrantLock();

    public OrderCore(String id,Integer number) {
        this.id = id;
        this.number = number;
    }

    @Override
    public void run() {
        if (number>0){
            //写法一 使用lock锁
//            lock.lock();
//            for(int i=4;i>0;i--){
//                number--;
//                logger.info((Thread.currentThread().getName())+"  number  "+number);
//            }
//            lock.unlock();

            //写法二 使用synchronized锁
            synchronized (this){
                for(int i=4;i>0;i--){
                    number--;
                    logger.info((Thread.currentThread().getName())+"  number  "+number);
                }
            }
        }
    }
}
